﻿/*******************************************************************************
 **  Name:                                        **
 **  Description:                                                             **
 **                                                                           **
 **  CDDL: Open Source Initiative (OSI) Approved License                            **
 **                                                                           **
 **  Copyright (c) 2009-2010 Barry "Gian" James  <bjames@munixos.net>         **
 **  All rights reserved.                                                     **
 **                                                                           **
 **  The contents of this file are subject to the terms of the CDDL:          **
 **  Common Development and Distribution License (the "License").             **
 **  You may not use this file except in compliance with the License.         **
 **                                                                           **
 **  You can obtain a copy of the license at $PROJECT_ROOT/LICENSE            **
 **  or http://www.opensolaris.org/os/licensing.  This code is Open Source    **
 **  and you are free to use it within the confines of the license, even      **
 **  for your own closed-source commercial projects, as long as you follow    **
 **  the terms set forth in the CDDL.                                         **
 **                                                                           **
 **  When distributing Covered Code, include this CDDL HEADER in each         **
 **  file and include the License file at $PROJECT_ROOT/LICENSE.              **
 **  If applicable, add the following below this CDDL HEADER, with the        **
 **  fields enclosed by brackets "[]" replaced with your own identifying      **
 **  information: Portions Copyright [yyyy] [name of copyright owner]         **
 **                                                                           **
 ******************************************************************************/
// Created on November 1, 2010, 7:25 AM
// Modified $Date$ by $Author$
// $Id$

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;
using System.Xml.Linq;

namespace sat1baf1
{
    public class WeaponSize
    {
        public enum WpnSz { N, F, D, T, S, M, L, H, G, C, E, V };
        public string Name;
        public char Abbr;
        public short Defense = 0;
        public short Attack = 0;
        public short StealthHide = 0;
        public short Wounds = 0;     // have to determine this on the fly (WoundsConst * CON)
        public float WoundsConst;
        public string WoundsStr = @"{0:F} * CON";  // eg 1/8 * CON
        public string EncumbranceStr = @"{0:F} * standard";   // eg "0.25 * standard"
        public short Encumbrance = 0;
        public float EncumbranceConst = 0;
        public string Squares;
        public short Reach = 0;



    }

    public class WeaponQuality
    {
        public string Name;
        public string Abbr;
        public string Desc;
    }

    public class Weapon
    {
        private string name;
        private string type;
        public short Pick;
        public short Attack;
        public string Damage;
        public short DamageVal;
        public string ET;
        public short ETVal;
        public string Ammo;
        public short Recoil;
        public short Range;
        public string Size;
        public WeaponSize WpnSz;
        public short Hands = 0; // 0 = mounted, 1=1h, 2=2h
        public WeaponQuality Qualities;
        public float Weight;
        public short[] Complexity = { 0, 0 };
        public int StreetValue;
        public WeaponType code;
        public short untrainedPenalty;
        public short dmgSave;

        public Weapon()
        {
        }

        public enum WeaponType
        {
            UNARMED, BLUNT, B_EXOTIC, EDGED, E_EXOTIC, EXPLOSIVES, GUIDED, HANDGUN,
            HURLED, H_EXOTIC, INDIRECT, RIFLE, SHOTFUN, SUBMACHINEGUN, TACTICAL, VEHICLE
        };

        public string Name { get { return name; } set { name = value; } }
        public string Type { get { return type; } set { type = value; } }
        public static string MagType(char cMagType)
        {
            if (cMagType == 'M') return "magazines";
            else if (cMagType == 'S') return "internals";
            else if (cMagType == 'B') return "belts";
            else if (cMagType == 'D') return "drums";
            else return "unknowns";
        }
    }


    public sealed class WeaponDB
    {
        static string _fileName;
        XElement _x;

        static WeaponDB _instance;
        public static WeaponDB Instance
        {
            get
            {
                if (_instance == null)
                    _instance = new WeaponDB();
                return _instance;
            }
        }

        private WeaponDB()
        {
            _fileName = @"Data Files\Weapons.xml";
            _x = XElement.Load(_fileName); // Root element
            XmlLog.Instance.Add("Loaded WeaponDB log from " + _fileName);
        }

        public Weapon GetWeapon(string name)
        {
            IEnumerable<XElement> wpn =
                from el in _x.Elements("NAME")
                where (string)el.Element("NAME") == name
                select el;

            Weapon newWeapon = new Weapon();
            foreach (XElement el in wpn)
            {

            }
            return newWeapon;
        }
        public IEnumerable<XElement> FindWeaponByName(string name)
        {
            IEnumerable<XElement> wpn =
                from el in _x.Elements("NAME")
  //              where (string)el.Element("NAME") == name
                select el;

            return wpn;
        }
        public IEnumerable<XElement> FindWeaponByNode(string node)
        {
            // The event arg name is the name of the node
#if DEBUG
            XmlLog.Instance.Add("FindWeaponByNode: Looking for <NAME id=\" " + node + "\">");
            
#endif
            IEnumerable<XElement> wpn = 
                from x in _x.Elements("WEAPON")
                where (string)x.Element("NAME").Attribute("id") == node
                select x;
            
            return wpn;
        }

        public void Add(XElement newWeapon)
        {
            _x.Add(newWeapon);
            _x.Save(_fileName);
        }

        public void Clear()
        {
            _x.RemoveNodes();
            _x.Save(_fileName);
        }


        // Properties
        // Read-only
        public XElement Arsenal { get { return _x; } }

    }


    ///// <summary>
    ///// Reads and contains all the weapon qualities.
    ///// Includes an indexer.
    ///// </summary>
    //public class WeaponList
    //{
    //    private Weapon[] list;
    //    const string FILE_WPNLIST = "..\\..\\..\\Data Files Backup\\Weapons.txt";
    //    const int NUMWPNS = 1;
    //    const int NUMWPNELEM = 17;
    //    public WeaponList()
    //    {
    //        list = new Weapon[NUMWPNS];
    //    }

    //    public Weapon[] List { get { return list; } }
    //}

    /// <summary>
    /// Reads and contains all the weapon qualities.
    /// Includes an indexer.
    /// </summary>
    public class WeaponQualityList
    {
        private WeaponQuality [] list;
        const string FILE_WPNQUAL = "..\\..\\..\\Data Files Backup\\WeaponQualities.txt";

        public WeaponQualityList()
        {
            list = new WeaponQuality[50];
        }
        public int LoadFile()
        {
            int count = 0;
            try
            {
                // Create an instance of StreamReader to read from a file.
                // The using statement also closes the StreamReader.
                using (StreamReader sr = new StreamReader(FILE_WPNQUAL))
                {
                    String line;
                    String [] strary = new String[3];
                    // Read and display lines from the file until the end of 
                    // the file is reached.
                    
                    while ((line = sr.ReadLine()) != null)
                    {
                        WeaponQuality newobj = new WeaponQuality();

                        strary = line.Split(':');
                        newobj.Name = strary[0];
                        newobj.Abbr = strary[1];
                        newobj.Desc = strary[2];
                        list[count++] = newobj;

                        //Console.WriteLine(line);
                    }
                }
            }
            catch (Exception e)
            {
                // Let the user know what went wrong.
                System.Windows.Forms.MessageBox.Show("The file could not be read:" + FILE_WPNQUAL);
                System.Windows.Forms.MessageBox.Show(e.Message);
                
                return 0;
            }

            return count;
        }
        // Indexer
        public WeaponQuality this[int index]
        {
            get
            {
                if (index < 0 || index >= list.Length)
                    throw new ArgumentOutOfRangeException();
                return list[index];
            }
            set
            {
                list[index] = value;
            }
        }

        public enum WpnQualIdx
        {
            ACC, AIR, AP, BLD, BLK, CLS, CMP, DEP, DST, FIN, FRG, FAT, GAR, GUI, HDM, HOK,
            IMP, INA, IND, INJ, INS, KEN, NKL, MAC, MAS, NUL, NFM, ONE, ORN, OVH, QKY, RCH,
            RGD, SAF, SLA, SLD, SPA, SUR, TKD, TBR, TOW, TRO, TPD, TRP, UNR, UPG
        };

        public WeaponQuality[] GetList { get { return list; } }
    }

    public class WeaponSizeList
    {
        private WeaponSize[] list;
        const string FILE_WPNSIZE = "..\\..\\..\\Data Files Backup\\WeaponSize.txt";
 //      const string FILE_WPNSIZE = "Data Files\\WeaponSize.txt";
        const int WPNSIZENUM = 10;
        const int WPNSIZES = 12;
        public WeaponSizeList()
        {
            list = new WeaponSize[WPNSIZES];
        }
        public int LoadFile()
        {
            int count = 0;
            try
            {
                // Create an instance of StreamReader to read from a file.
                // The using statement also closes the StreamReader.
                using (StreamReader sr = new StreamReader(FILE_WPNSIZE))
                {
                    String line;
                    String[] strary = new String[WPNSIZENUM];
                    // Read and display lines from the file until the end of 
                    // the file is reached.

                    while ((line = sr.ReadLine()) != null)
                    {
                        WeaponSize newobj = new WeaponSize();
                        if (line.StartsWith("#")) continue;
                       
                        strary = line.Split(':');
                        newobj.Name = strary[0];
                        newobj.Abbr = strary[1][0];
                        newobj.Defense = Convert.ToInt16(strary[2]);
                        newobj.Attack = Convert.ToInt16(strary[3]);
                        newobj.StealthHide = Convert.ToInt16(strary[4]);
                        newobj.WoundsConst = (float)Convert.ToDouble(strary[5]);
                        // Skipping strary[6] as it is just "CON"
                        newobj.EncumbranceConst = (float)Convert.ToDouble(strary[7]);
                        newobj.Squares = strary[8];
                        newobj.Reach = Convert.ToInt16(strary[9]);

                        list[count++] = newobj;

                        //Console.WriteLine(line);
                    }
                }
            }
            catch (Exception e)
            {
                // Let the user know what went wrong.
                //System.Windows.Forms.MessageBox.Show("The file could not be read:" + FILE_WPNSIZE);
                System.Windows.Forms.MessageBox.Show(e.Message);

                return 0;
            }

            return count;
        }

        public WeaponSize[] GetList { get { return list; } }
    }
}
